home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / krig2d.pro < prev    next >
Text File  |  1997-07-08  |  10KB  |  285 lines

  1. ; $Id: krig2d.pro,v 1.9 1997/04/28 19:38:43 dave Exp $
  2. ; Copyright (c) 1993-1997, Research Systems, Inc. All rights reserved. 
  3. ;    Unauthorized reproduction prohibited. 
  4.  
  5. FUNCTION Krig_expon, d, t       ;Return Exponential Covariance Fcn
  6. r = t[2] * exp((-3./t[0]) * d)
  7. z = where(d eq 0.0, count)
  8. if count gt 0 then r[z] = t[1] + t[2]
  9. return, r
  10. end
  11.  
  12. FUNCTION Krig_sphere, d, t      ;Return Spherical Covariance Fcn
  13. r = d/t[0] < 1.0                ;Normalized distance
  14. r = t[2] * (1. - 1.5 * r + 0.5 * r^3)
  15. z = where(d eq 0.0, count)
  16. if count gt 0 then r[z] = t[1] + t[2]
  17. return, r
  18. end
  19.  
  20. FUNCTION krig2d, z, x, y, REGULAR = regular, XGRID=xgrid, $
  21.     XVALUES = xvalues, YGRID = ygrid, YVALUES = yvalues, $
  22.     GS = gs, BOUNDS = bounds, NX = nx0, NY = ny0, EXPONENTIAL = ex, $
  23.     SPHERICAL = sp, NESTED = nest, C0 = C0
  24.  
  25. ;+ 
  26. ; NAME: 
  27. ;    KRIG_2D 
  28. ; PURPOSE: 
  29. ;    This function interpolates a regularly or irregularly gridded
  30. ;    set of points Z = F(X,Y) using kriging.
  31. ;
  32. ; CATEGORY: 
  33. ;    Interpolation, Surface Fitting 
  34. ;
  35. ; CALLING SEQUENCE: 
  36. ;    Result = KRIG2D(Z [, X, Y]) 
  37. ;
  38. ; INPUTS: 
  39. ;    X, Y, Z:  arrays containing the X, Y, and Z coordinates of the 
  40. ;          data points on the surface. Points need not be 
  41. ;          regularly gridded. For regularly gridded input data, 
  42. ;          X and Y are not used: the grid spacing is specified 
  43. ;          via the XGRID and YGRID (or XVALUES and YVALUES) 
  44. ;          keywords, and Z must be a two dimensional array. 
  45. ;          For irregular grids, all three parameters must be
  46. ;          present and have the same number of elements. 
  47. ;
  48. ; KEYWORD PARAMETERS: 
  49. ;   Model Parameters:
  50. ;    EXPONENTIAL: if set (with parameters [A, C0, C1]), use an exponential
  51. ;             semivariogram model.
  52. ;    SPHERICAL:   if set (with parameters [A, C0, C1]), use a spherical
  53. ;             semivariogram model.
  54. ;
  55. ;   Both models use the following parameters:
  56. ;    A:      the range. At distances beyond A, the semivariogram 
  57. ;          or covariance remains essentialy constant. 
  58. ;          See the definition of the functions below. 
  59. ;    C0:      the "nugget," which provides a discontinuity at the
  60. ;          origin. 
  61. ;    C1:      the covariance value for a zero distance, and the variance
  62. ;          of the random sample Z variable. If only a two element
  63. ;          vector is supplied, C1 is set to the sample variance.
  64. ;          (C0 + C1) = the "sill," which is the variogram value for
  65. ;          very large distances.
  66. ;
  67. ;  Input grid description:
  68. ;    REGULAR:  if set, the Z parameter is a two dimensional array 
  69. ;          of dimensions (N,M), containing measurements over a 
  70. ;          regular grid. If any of XGRID, YGRID, XVALUES, YVALUES 
  71. ;          are specified, REGULAR is implied. REGULAR is also 
  72. ;          implied if there is only one parameter, Z. If REGULAR is 
  73. ;          set, and no grid (_VALUE or _GRID) specifications are 
  74. ;          present, the respective grid is set to (0, 1, 2, ...). 
  75. ;    XGRID:    contains a two element array, [xstart, xspacing], 
  76. ;          defining the input grid in the X direction. Do not
  77. ;          specify both XGRID and XVALUES. 
  78. ;    XVALUES:  if present, XVALUES(i) contains the X location 
  79. ;          of Z(i,j). XVALUES must be dimensioned with N elements. 
  80. ;    YGRID:    contains a two element array, [ystart, yspacing], 
  81. ;          defining the input grid in the Y direction. Do not
  82. ;          specify both YGRID and YVALUES. 
  83. ;    YVALUES:  if present, YVALUES(i) contains the Y location 
  84. ;          of Z(i,j). YVALUES must be dimensioned with N elements. 
  85. ;
  86. ;  Output grid description:
  87. ;    GS:      If present, GS must be a two-element vector [XS, YS],
  88. ;          where XS is the horizontal spacing between grid points
  89. ;          and YS is the vertical spacing. The default is based on
  90. ;          the extents of X and Y. If the grid starts at X value
  91. ;          Xmin and ends at Xmax, then the default horizontal
  92. ;          spacing is (Xmax - Xmin)/(NX-1). YS is computed in the
  93. ;          same way. The default grid size, if neither NX or NY
  94. ;          are specified, is 26 by 26. 
  95. ;    BOUNDS:   If present, BOUNDS must be a four element array containing
  96. ;          the grid limits in X and Y of the output grid:
  97. ;          [Xmin, Ymin, Xmax, Ymax]. If not specified, the grid
  98. ;          limits are set to the extent of X and Y. 
  99. ;    NX:       The output grid size in the X direction. NX need not
  100. ;            be specified if the size can be inferred from GS and
  101. ;          BOUNDS. The default value is 26.
  102. ;    NY:       The output grid size in the Y direction. See NX. 
  103. ; OUTPUTS: 
  104. ;    This function returns a two dimensional floating point array
  105. ;    containing the interpolated surface, sampled at the grid points.
  106. ;
  107. ; RESTRICTIONS:
  108. ;    The accuracy of this function is limited by the single precision
  109. ;    floating point accuracy of the machine.
  110. ;
  111. ;        SAMPLE EXECUTION TIMES (measured on a Sun IPX)
  112. ;    # of input points    # of output points    Seconds
  113. ;    10            676            1.1
  114. ;    20            676            1.5
  115. ;    40            676            2.6
  116. ;    80            676            7.8
  117. ;    10            1024            1.6
  118. ;    10            4096            5.9
  119. ;    10            16384            23
  120. ;
  121. ; PROCEDURE: 
  122. ;    Ordinary kriging is used to fit the surface described by the
  123. ;    data points X,Y, and Z. See: Isaaks and Srivastava,
  124. ;    "An Introduction to Applied Geostatistics," Oxford University
  125. ;    Press, 1989, Chapter 12.
  126. ;
  127. ;    The parameters of the data model, the range, nugget, and
  128. ;    sill, are highly dependent upon the degree and type of spatial
  129. ;    variation of your data, and should be determined statistically.
  130. ;    Experimentation, or preferrably rigorus analysis, is required.
  131. ;
  132. ;    For N data points, a system of N+1 simultaneous
  133. ;    equations are solved for the coefficients of the 
  134. ;    surface. For any interpolation point, the interpolated value 
  135. ;    is: 
  136. ;          F(x,y) = Sum( w(i) * C(x(i),y(i), x, y)
  137. ;
  138. ;    Formulas used to model the variogram functions:
  139. ;        d(i,j) = distance from point i to point j.
  140. ;        V = variance of samples.
  141. ;        C(i,j) = Covariance of sample i with sample j.
  142. ;               C(x0,y0,x1,y1) = Covariance of point (x0,y0) with (x1,y1).
  143. ;
  144. ;       Exponential covar: C(d) = C1 * EXP(-3*d/A)   if d ne 0.
  145. ;                               = C1 + C0          if d eq 0.
  146. ;
  147. ;       Spherical covar:   C(d) = (1.0 - 1.5 * d/a + 0.5 * (d/a)^3)
  148. ;                               = C1 + C0           if d eq 0.
  149. ;                               = 0                 if d > a.
  150. ;
  151. ; EXAMPLES:
  152. ; Example 1: Irregularly gridded cases 
  153. ;    Make a random set of points that lie on a gaussian: 
  154. ;      n = 15        ;# random points
  155. ;      x = RANDOMU(seed, n) 
  156. ;      y = RANDOMU(seed, n) 
  157. ;      z = exp(-2 * ((x-.5)^2 + (y-.5)^2))    ;The gaussian 
  158. ;
  159. ;     get a 26 by 26 grid over the rectangle bounding x and y: 
  160. ;      e = [ 0.25, 0.0]    ;Range and nugget are 0.25, and 0.
  161. ;                ;(These numbers are dependent upon
  162. ;                ;your data model.)
  163. ;      r = krig2d(z, x, y, EXPON = e)    ;Get the surface. 
  164. ;
  165. ;     Or: get a surface over the unit square, with spacing of 0.05: 
  166. ;      r = krig2d(z, x, y, EXPON=e, GS=[0.05, 0.05], BOUNDS=[0,0,1,1])
  167. ;
  168. ;     Or: get a 10 by 10 surface over the rectangle bounding x and y: 
  169. ;      r = krig2d(z, x, y, EXPON=e, NX=10, NY=10) 
  170. ; Example 2: Regularly gridded cases 
  171. ;      s = [ 10., 0.2]            ;Range and sill, data dependent.
  172. ;      z = randomu(seed, 5, 6)        ;Make some random data
  173.  
  174. ;    interpolate to a 26 x 26 grid: 
  175. ;      CONTOUR, krig2d(z, /REGULAR, SPHERICAL = s)
  176. ; MODIFICATION HISTORY: 
  177. ;    DMS, RSI, March, 1993. Written.
  178. ;-
  179.  
  180. on_error, 2
  181.  
  182. s = size(z)        ;Assume 2D
  183. nx = s[1]
  184. ny = s[2]
  185.  
  186. reg = keyword_set(regular) or (n_params() eq 1)
  187.  
  188. if n_elements(xgrid) eq 2 then begin
  189.     x = findgen(nx) * xgrid[1] + xgrid[0]
  190.     reg = 1
  191. endif else if n_elements(xvalues) gt 0 then begin
  192.     if n_elements(xvalues) ne nx then $
  193.         message,'Xvalues must have '+string(nx)+' elements.'
  194.     x = xvalues
  195.     reg = 1
  196. endif
  197.  
  198. if n_elements(ygrid) eq 2 then begin
  199.     y = findgen(ny) * ygrid[1] + ygrid[0]
  200.     reg = 1
  201. endif else if n_elements(yvalues) gt 0 then begin
  202.     if n_elements(yvalues) ne ny then $
  203.         message,'Yvalues must have '+string(ny)+' elements.'
  204.     y = yvalues
  205.     reg = 1
  206. endif
  207.  
  208. if reg then begin
  209.     if s[0] ne 2 then message,'Z array must be 2D for regular grids'
  210.     if n_elements(x) ne nx then x = findgen(nx)
  211.     if n_elements(y) ne ny then y = findgen(ny)
  212.     x = x # replicate(1., ny)    ;Expand to full arrays.
  213.     y = replicate(1.,nx) # y
  214.     endif
  215.  
  216. n = n_elements(x)
  217. if n ne n_elements(y) or n ne n_elements(z) then $
  218.     message,'x, y, and z must have same number of elements.'
  219.  
  220. if keyword_set(ex) then begin       ;Get model params
  221.     t = ex
  222.     fname = 'KRIG_EXPON'
  223. endif else if keyword_set(sp) then begin
  224.     t = sp
  225.     fname = 'KRIG_SPHERE'
  226. endif else MESSAGE,'Either EXPONENTIAL or SPHERICAL model must be selected.'
  227.  
  228. if n_elements(t) eq 2 then begin    ;Default value for variance?
  229.     mz = total(z) / n        ;Mean of z
  230.     var = total((z - mz)^2)/n    ;Variance of Z
  231.     t = [t, var-t[1]]    ;Default value for C1
  232.     endif
  233.  
  234. m = n + 1            ;# of eqns to solve
  235. a = fltarr(m, m)
  236.  
  237. for i=0, n-2 do for j=i,n-1 do begin  ;Only upper diagonal elements
  238.     d = (x[i]-x[j])^2 + (y[i]-y[j])^2  ;Distance squared
  239.     a[i,j] = d & a[j,i] = d             ;symmetric
  240.     endfor
  241.  
  242. a = call_function(fname, sqrt(a), t)        ;Get coefficient matrix
  243. a[n,*] = 1.0            ;Fill edges
  244. a[*,n] = 1.0
  245. a[n,n] = 0.0
  246.  
  247. ; c = invert(a)           ;Solution using inverse
  248. ludcmp, a, indx, even_odd       ;Solution using LU decomposition
  249.  
  250. if n_elements(nx0) le 0 then nx0 = 26    ;Defaults for nx and ny
  251. if n_elements(ny0) le 0 then ny0 = 26
  252.  
  253. xmin = min(x, max = xmax)        ;Make the grid...
  254. ymin = min(y, max = ymax)
  255.  
  256. if n_elements(bounds) lt 4 then bounds = [xmin, ymin, xmax, ymax]
  257.  
  258. if n_elements(gs) lt 2 then $   ;Compute grid spacing from bounds
  259.   gs = [(bounds[2]-bounds[0])/(nx0-1.), (bounds[3]-bounds[1])/(ny0-1.)]
  260.  
  261. nx = ceil((bounds[2]-bounds[0])/gs[0])+1    ;# of elements
  262. ny = ceil((bounds[3]-bounds[1])/gs[1])+1
  263.  
  264. d = fltarr(m)                       ;One extra for lagrange constranint
  265. r = fltarr(nx,ny,/nozero)           ;Result
  266.  
  267. for j=0,ny-1 do begin               ;Each output point
  268.   y0 = bounds[1] + gs[1] * j
  269.   for i=0,nx-1 do begin
  270.     x0 = bounds[0] + gs[0] * i
  271.     d[0] = sqrt((x-x0)^2 + (y-y0)^2) ;distance
  272.     d = call_function(fname, d, t)          ;Get rhs
  273.     d[n] = 1.0                              ;lagrange constr
  274.     lubksb, a, indx, d
  275.     r[i,j] = total(d * z)
  276.   endfor
  277. endfor
  278. return, r
  279. end
  280.